package com.lantosec.hmrp.modules.form.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lantosec.hmrp.core.kit.Page;
import com.lantosec.hmrp.core.kit.PageVO;
import com.lantosec.hmrp.core.kit.Result;
import com.lantosec.hmrp.modules.form.entity.FormColumns;
import com.lantosec.hmrp.modules.form.entity.FormTable;
import com.lantosec.hmrp.modules.form.enumeration.FormTableDefEnum;
import com.lantosec.hmrp.modules.form.enumeration.TableDefEnum;
import com.lantosec.hmrp.modules.form.mapper.FormTableMapper;
import com.lantosec.hmrp.modules.form.service.IFormColumnsService;
import com.lantosec.hmrp.modules.form.service.IFormTableService;
import com.lantosec.hmrp.modules.form.vo.FormTableVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 自定义表单表定义 服务实现类
 * </p>
 *
 * @author AutoCode
 * @since 2020-04-15
 */
@Service
@Primary
@Log4j2
public class FormTableServiceImpl extends ServiceImpl<FormTableMapper, FormTable> implements IFormTableService {

    @Autowired
    IFormColumnsService formColumnsService;

    @Override
    public List<FormTable> queryPrimary(String tableSchema) {
        String def = "PRIMARY";
        List<FormTable> list = baseMapper.selectList(new QueryWrapper<FormTable>()
                .eq(String.valueOf(FormTable.ColName.table_def), def)
                .eq(StringUtils.isNotEmpty(tableSchema), String.valueOf(FormTable.ColName.table_schema), tableSchema));

        return list;
    }

    @Override
    public List<FormTable> querySublist(String parentId) {
        List<FormTable> list = baseMapper.selectList(new QueryWrapper<FormTable>()
                .eq(String.valueOf(FormTable.ColName.table_def), FormTableDefEnum.DETAILED.getType())
                .eq(String.valueOf(FormTable.ColName.parent_id), parentId)
                .orderByDesc(String.valueOf(FormTable.ColName.create_date))
        );

        return list;
    }

    @Override
    public Page<FormTableVO> page(PageVO<FormTable> page, FormTable condition) {
        List<FormTableVO> list = new ArrayList<>();
        page = super.getBaseMapper().selectPage(page, new QueryWrapper<FormTable>()
                .eq(String.valueOf(FormTable.ColName.table_def), TableDefEnum.PRIMARY.getType())
                .eq(StringUtils.isNotEmpty(condition.getTableId()), String.valueOf(FormTable.ColName.table_id), condition.getTableId())
                .like(StringUtils.isNotEmpty(condition.getTableComment()), String.valueOf(FormTable.ColName.table_comment), condition.getTableComment())
                .orderByDesc(String.valueOf(FormTable.ColName.create_date))
        );

        page.getRecords().forEach(item -> {
            FormTableVO vo = new FormTableVO(item);
            // 查询关联的详情表
            List<FormTable> childList = baseMapper.selectList(new QueryWrapper<FormTable>()
                    .eq(String.valueOf(FormTable.ColName.parent_id), item.getTableId())
                    .orderByDesc(String.valueOf(FormTable.ColName.create_date))
            );

            vo.setChildList(childList);
            list.add(vo);
        });
        Page<FormTableVO> resultPge = new Page<>();
        resultPge.setPage(page.getPageNo().intValue());
        resultPge.setTotal(page.getTotal());
        resultPge.setPageSize(page.getPageSize().intValue());
        resultPge.setRows(list);
        return resultPge;
    }

    /**
     * 保存
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> save(FormTableVO vo) {
        FormTable formTable = vo.convertToEntity();
        // 判断表是否存在
        if (!isExist(formTable)) {
            return Result.fail("表名已经存在");
        }
        Date date = new Date();
        formTable.setCreateDate(date);
        boolean flag = super.save(formTable);
        if (flag) {
            // 批量插入列
            List<FormColumns> columns = vo.getColumns();
            columns.forEach(item-> {
                item.setCreateDate(date);
                item.setCreateUserId(formTable.getCreateUserId());
                item.setCreateUserName(formTable.getCreateUserName());
                item.setTableId(formTable.getTableId());
            });
            flag = formColumnsService.saveBatch(columns);
        }
        return Result.ok(formTable.getTableId());
    }

    @Override
    public Result<Void> update(FormTable entity) {
        if (!isExist(entity)) {
            return Result.fail("表名已经存在");
        }
        boolean flag = super.updateById(entity);
        if(!flag) {
            return Result.fail("保存失败");
        }
        return Result.ok();
    }

    /**
     * 同一数据库不能有相同的表名
     *
     * @param entity
     * @return
     */
    private boolean isExist(FormTable entity) {
        /*Integer count = baseMapper.selectCount(new QueryWrapper<FormTable>()
                .eq(StringUtils.isNotBlank(entity.getTableId()), String.valueOf(FormTable.ColName.table_id), entity.getTableId())
                .eq(String.valueOf(FormTable.ColName.table_schema), entity.getTableSchema())
                .eq(String.valueOf(FormTable.ColName.table_name), entity.getTableName()));
        if (count > 0) {
            return false;
        }*/
        return true;
    }

    /***
     * TODO 生成SQL
     *
     * @param action    CREATE 添加，ALTER 修改，DELETE 删除
     * @param entity
     * @return
     */
    private String generatorSql(String action, FormTable entity, List<FormColumns> columns) {

        StringBuilder sql = new StringBuilder();
        switch (action) {
            case "CREATE":
                if (CollectionUtils.isEmpty(columns)) {
                    return null;
                }
                sql.append("CREATE TABLE" + entity.getTableName());
                sql.append("(");
                List<String> primaryKeyList = new ArrayList();
                List<String> foreignKeyList = new ArrayList();
                // TODO 字段列表根据ordinalPosition字段排序
                for (FormColumns item : columns) {
                    // 字段名
                    sql.append("'" + item.getColumnName() + "' ");
                    // 字段类型
                    sql.append(item.getDataType() + " ");
                    // 字段长度
                    if ("char".equals(item.getDataType())) {
                        sql.append("(" + item.getCharacterMaximumLength() + ") ");
                    } else if ("int".equals(item.getDataType())) {
                        sql.append("(" + item.getNumericPrecision() + "," + item.getNumericScale() + ") ");
                    }
                    if ("datetime".equals(item.getDataType())) {
                        sql.append("(" + item.getDatetimePrecision() + ") ");
                    }
                    // 是否为空
                    if ("NO".equals(item.getIsNullable())) {
                        sql.append("NOT ");
                    }
                    sql.append("NULL ");
                    // 描述
                    sql.append("'" + item.getColumnComment() + "', ");
                    // 是否是主键
                    if (item.getPrimaryKey()) {
                        primaryKeyList.add(item.getColumnName());
                    }
                    // 是否是外键
                    if (item.getForeignKey()) {
                        foreignKeyList.add(item.getColumnName());
                    }

                }
                // 主键
                if(CollectionUtils.isNotEmpty(primaryKeyList)) {
                    sql.append("PRIMARY KEY (" + String.join(",",primaryKeyList) + ")");
                }
                // 外键
                if(CollectionUtils.isNotEmpty(foreignKeyList)) {
                    sql.append("FOREIGN KEY (" + String.join(",",foreignKeyList) + ")");
                }
                break;
            case "ALTER":
                break;
            case "DELETE":
                sql.append("DROP TABLE " + entity.getTableName());
                break;
            default:
                break;
        }
        return sql.toString();
    }
}
